/* Gionata Massi <gionata.massi@gmail.com>
 * Febbraio 2007
 *
 * File: matrixio.cpp
 *
 * Questo file fa parte di 'aga'
 */

/*!
  \file		matrixio.cpp
  \brief	Solutore MOSP e MOSPk mediante algoritmo genetico.
  \author	Gionata Massi
  \version	2009-07-23
  \date		2007-03-22

  Operazioni di input matrice di produzione.
 */

#include "aga.h"

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <list>
#include <vector>
#include <cmath>
#include <cstdlib>

using namespace std;

//! Legge gli schemi da file e restituisce la relativa matrice.
/*!
  Legge gli schemi dal file indicato da \p filename e restituisce la relativa
  matrice. In uscita \p nPatterns contiene il numero di schemi letti e
  \p nPieces il numero di pezzi che li compongono.
  In caso di errore restituisce \p NULL.

  \param filename	Il nome dei file dei dati
  \param[out] nPatterns	Il numero di schemi (righe)
  \param[out] nPieces	Il numero di pezzi (colonne)
  \return		La matrice, o NULL in caso di errore
*/
void ReadData(GeneticData *data, char *filename)
{
	ifstream instanceFile(filename);
	if (instanceFile.fail()) {
		cerr << "Brutto cazzone, mettimi un file che riesca a trovare." << endl;
		exit(1);
	}

	string line;
	for (int i = 0; i < 5; i++)
		getline(instanceFile, line);

	istringstream linestream(line);
	linestream >> data->NumVehicles >> data->VehicleCapacity;

	for (int i = 0; i < 5; i++)
		getline(instanceFile, line);

	int no;
	vector <Customer *> &nodes = data->CustomerSet;
	linestream.clear();
	linestream.str(line);
	while (!line.empty()) {
		linestream >> no;
		Customer *currNode = new Customer();
		currNode->Number = no;
		linestream >> currNode->XCoord;
		linestream >> currNode->YCoord;
		linestream >> currNode->Demand;
		linestream >> currNode->ReadyTime;
		linestream >> currNode->DueDate;
		linestream >> currNode->ServiceTime;
		nodes.push_back(currNode);
		getline(instanceFile, line);
		linestream.clear();
		linestream.str(line);
	}

	instanceFile.close();

	int N = data->NumGenes = nodes.size() - 1;
	int size = (N) * (N+1) / 2;
	vector <double> &distance = data->Distance;
	distance.resize(size);

	for (int ii = 0; ii < N + 1; ii++)
		for (int jj = ii + 1; jj < N+ 1; jj++) {
			int idx = (int) (jj*(double)(jj-1)/2+ii);
			distance[idx] =
			    sqrt((nodes[ii]->XCoord - nodes[jj]->XCoord)*(nodes[ii]->XCoord - nodes[jj]->XCoord) + (nodes[ii]->YCoord - nodes[jj]->YCoord)*(nodes[ii]->YCoord - nodes[jj]->YCoord));
		}
}
